package com.github.alenfive.utils;

import java.security.MessageDigest;
import java.util.UUID;

/**
 * md5值转成char[]数组，每位加16，把整个md5值转成纯大写字母的字符串
 */
public class MD5Utils {
    public static void main(String[] args) {
        for (int i = 0; i < 10000; i++) {
            System.out.println(md5SupperLetter(UUID.randomUUID().toString()));
        }
    }

    /**
     * 获取字符串的MD5值
     * @param message
     */
    public static String md5(String message) {
        return md5(message.getBytes());
    }

    /**
     * 获取byte数组的MD5值
     * @param input
     */
    public static String md5(byte[] input) {
        try {
            // 1 创建一个提供信息摘要算法的对象，初始化为md5算法对象
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 2 计算后获得字节数组,这就是那128位了
            byte[] buff = md.digest(input);
            // 3 把数组每一字节（一个字节占八位）换成16进制连成md5字符串
            return bytesToSupperHex(buff);
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * 生成md5，把整个md5值转成纯大写字母的字符串
     * @param message
     */
    public static String md5SupperLetter(String message) {
        return md5SupperLetter(message.getBytes());
    }

    /**
     * 生成md5，把整个md5值转成纯大写字母的字符串
     * @param input
     */
    public static String md5SupperLetter(byte[] input) {
        String md5 = md5(input);
        StringBuffer supperLetter = new StringBuffer();
        char[] array = md5.toCharArray();
        for (int i = 0; i < array.length; i++) {
            // 把字符串的每个char加17，让数字全部变成大写字母
            char result = (char) (array[i]+17);
            supperLetter.append(result);
        }
        return supperLetter.toString();
    }

    /**
     * 二进制转大写字母的十六进制
     * @param bytes
     */
    public static String bytesToSupperHex(byte[] bytes) {
        StringBuffer md5str = new StringBuffer();
        // 把数组每一字节换成16进制连成md5字符串
        for (int i = 0; i < bytes.length; i++) {
            int digital = bytes[i];

            if (digital < 0) {
                digital += 256;
            }
            if (digital < 16) {
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        return md5str.toString().toUpperCase();
    }

}
